package com.xyz.FileTest.FilterMode;

import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    public static void main(String[] args) throws IOException {
        // 定义了一个字节数组，里面存的是字符串按 UTF-8 编码转换成的二进制字节数组
        byte[] data = "hello, world!".getBytes("UTF-8");
        // 用 try 结构保证自动关闭输入流对象，释放资源
        // 用到的是自定义的 输入流对象，继承了 FilterInputStream
        // 添加了对读入文件大小计量的功能
        // Filter 模式构建的输入流，是以其他输入流对象作为构造器的参数的
        // 实际上就是对其他输入流功能的二次包装，通过 Filter 模式，增加新的功能到输入流中
        try (CountInputStream input = new CountInputStream(new ByteArrayInputStream(data))) {
            int n;
            while ((n = input.read()) != -1) {
                System.out.println((char)n);
            }
            System.out.println("一共读取了 " + input.getBytesRead() + " 字节");
        }
    }
}

// 自定义的一个继承自 FilterInputStream 的派生类
class CountInputStream extends FilterInputStream {

    //私有字段 count，返回输入流的长度
    // 即输入流读取文件的长度
    private int count = 0;

    // 构造器，用到了一个输入流对象
    CountInputStream(InputStream in) {
        // 自定义类构造器中，调用了父类的构造器
        // 传入并获取一个输入流对象
        // 并初始化从父类中继承过来的 in 字段
        super(in);
    }

    // 取值器，返回 count
    public int getBytesRead() {
        return this.count;
    }

    // 公共方法，用来获取输入流读取到的值
    public int read() throws IOException {
        int n = in.read();
        if (n != -1) {
            this.count ++;
        }
        return n;
    }

    // 公共方法，加入缓冲处理方法，一次读取整个缓冲区内容
    public int read(byte[] b, int off, int len) throws IOException {
        int n = in.read(b, off, len);
        this.count += n;
        return n;
    }
}

